﻿using System;
using System.Diagnostics;

namespace CommonUtils
{
    /// <summary>
    /// 命令行
    /// </summary>
    public class CommandUtil
    {
        /// <summary>
        /// 执行cmd命令
        /// </summary>      
        public static ProcessExcuteInfo Run(string processAndArgs, string workspace = null, double exitSeconds = 0)
        {
            var startInfo = new ProcessStartInfo("cmd.exe");
            startInfo.Arguments = "/c " + processAndArgs; // /c不可省略

            if (!string.IsNullOrEmpty(workspace))
                startInfo.WorkingDirectory = workspace;

            return ProcessUtil.Start(startInfo, exitSeconds);
        }

        /// <summary>
        /// 执行cmd命令
        /// </summary> 
        public static ProcessExcuteInfo Execute(string processAndArgs, string workspace = null)
        => Run(processAndArgs, workspace);

        /*
        shutdown.exe -s：关机
        shutdown.exe -r：关机并重启
        shutdown.exe -l：注销当前用户        
        shutdown.exe -s -t 时间：设置关机倒计时
        shutdown.exe -h：休眠
        shutdown.exe -t 时间：设置关机倒计时。默认值是 30 秒。
        shutdown.exe -a：取消关机
        shutdown.exe -f：强行关闭应用程序而没有警告
        shutdown.exe -m \计算机名：控制远程计算机
        shutdown.exe -i：显示“远程关机”图形用户界面，但必须是Shutdown的第一个参数
        shutdown.exe -c "消息内容"：输入关机对话框中的消息内容
        shutdown.exe -d [u][p]:xx:yy ：列出系统关闭的原因代码：u 是用户代码 ，p 是一个计划的关闭代码 ，
        xx 是一个主要原因代码(小于 256 的正整数) ，yy 是一个次要原因代码(小于 65536 的正整数)
        */
        public static ProcessExcuteInfo Logoff()
        => Execute("shutdown -l");

        /// <summary>
        /// 改变当前系统时间
        /// </summary> 
        public static ProcessExcuteInfo SetTime(DateTime time)
        {
            Execute("date " + time.ToString("yyyy-MM-dd"));
            var result = Execute("time " + time.ToString("HH:mm:ss"));
            ThreadUtil.SleepSeconds(3);
            TimeUtil.NetRefresh();
            return result;
        }

        public static ProcessExcuteInfo Ping(string ip)
        => Execute("ping " + ip);

        public static ProcessExcuteInfo Start(string path)
        => Execute("start " + path.AddDoubleQuotes());

        /// <summary>
        /// 打开文件/ReplaceSpritRight2Left不可省略
        /// </summary>
        public static ProcessExcuteInfo Open(string path)
        => Execute("explorer " + path.ReplaceSpritRight2Left().AddDoubleQuotes());

        /// <summary>
        /// 打开文件
        /// </summary>
        public static ProcessExcuteInfo OpenFile(string path)
        => Open(path);

        /// <summary>
        /// 打开文件/ReplaceSpritRight2Left不可省略
        /// </summary>
        public static ProcessExcuteInfo OpenFolder(string path)
        => Execute("explorer " + path.ReplaceSpritRight2Left().AddDoubleQuotes());

        /// <summary>
        /// 打开文件/ReplaceSpritRight2Left不可省略
        /// </summary>
        public static ProcessExcuteInfo OpenFileFolder(string path)
        => Execute("explorer /select," + path.ReplaceSpritRight2Left().AddDoubleQuotes());

        public static ProcessExcuteInfo OpenUrl(string url)
        //=> Execute("start " + url.AddDoubleQuotes());//无效
        => Execute("explorer " + url.AddDoubleQuotes());

        /// <summary>
        /// 数据迁移命令
        /// 数据库实体类必须包含默认构造函数，否者EF创建实体失败，抛出此异常：
        /// Database operation expected to affect 1 row(s) but actually affected 0 row(s).
        /// </summary>
        public static string GetAddMigrationCommand(string name)
        => "add-migration " + name;

        /// <summary>
        /// 命令
        /// </summary>
        public static void CreateRunCommandFile(string assemblyName = null)
        {
            if (string.IsNullOrEmpty(assemblyName))
                assemblyName = ReflectionUtil.GetAssemblyName(2);
            var cmd = string.Format("dotnet {0}.dll\r\npause", assemblyName);
            FileUtil.Save(PathUtil.GetProjectFull("~run.cmd"), cmd, TextEncoding.UTF8NoBom);
        }

    }
}
